package com.atguigu.juc.atomics;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author yanglin
 * @create 2024-01-26 17:26 星期五
 * description:
 */
public class AccumulatorCompareDemo {

    /**
     * 
     */
    
    
    /**
     * 需求：50个线程，每个线程100W次，总点赞数
     */

    public static final int _1W = 10000;
    public static final int threadNumber = 50;

    public static void main(String[] args) throws InterruptedException {

        ClickNumber clickNumber = new ClickNumber();
        long startTime;
        long endTime;
        CountDownLatch countDownLatch1 = new CountDownLatch(threadNumber);
        CountDownLatch countDownLatch2 = new CountDownLatch(threadNumber);
        CountDownLatch countDownLatch3 = new CountDownLatch(threadNumber);
        CountDownLatch countDownLatch4 = new CountDownLatch(threadNumber);
        
        startTime = System.currentTimeMillis();
        for (int i = 0; i < threadNumber; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < _1W * 100; j++) {
                        clickNumber.add();
                    }
                }finally {
                    countDownLatch1.countDown();
                }
            }).start();
        }
        countDownLatch1.await();
        endTime = System.currentTimeMillis();
        System.out.println("add()耗时：" + (endTime - startTime) + ",结果是：" + clickNumber.num);

        startTime = System.currentTimeMillis();
        for (int i = 0; i < threadNumber; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < _1W * 100; j++) {
                        clickNumber.byAtomicLong();
                    }
                }finally {
                    countDownLatch2.countDown();
                }
            }).start();
        }
        countDownLatch2.await();
        endTime = System.currentTimeMillis();
        System.out.println("byAtomicLong()耗时：" + (endTime - startTime) + ",结果是：" + clickNumber.atomicLong.get());


        startTime = System.currentTimeMillis();
        for (int i = 0; i < threadNumber; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < _1W * 100; j++) {
                        clickNumber.byLongAdder();
                    }
                }finally {
                    countDownLatch3.countDown();
                }
            }).start();
        }
        countDownLatch3.await();
        endTime = System.currentTimeMillis();
        System.out.println("byLongAdder()耗时：" + (endTime - startTime) + ",结果是：" + clickNumber.longAdder.sum());

        startTime = System.currentTimeMillis();
        for (int i = 0; i < threadNumber; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < _1W * 100; j++) {
                        clickNumber.byLongAccumulator();
                    }
                }finally {
                    countDownLatch4.countDown();
                }
            }).start();
        }
        countDownLatch4.await();
        endTime = System.currentTimeMillis();
        System.out.println("byLongAccumulator()耗时：" + (endTime - startTime) + ",结果是：" + clickNumber.longAccumulator.get());
    }
}


//资源类
class ClickNumber {
    int num = 0;
    
    public synchronized void add(){
        num++;
    }
    
    AtomicLong atomicLong = new AtomicLong(0);
    public void byAtomicLong(){
        atomicLong.getAndIncrement();
    }
    
    LongAdder longAdder = new LongAdder();
    public void byLongAdder(){
        longAdder.increment();
    }
    
    LongAccumulator longAccumulator = new LongAccumulator(Long::sum,0);
    public void byLongAccumulator(){
        longAccumulator.accumulate(1);
    }
}
